const jwt = require('jsonwebtoken');
const { asyncHandler } = require('./errorMiddleware');
const { query, cache } = require('../config/database');
const logger = require('../utils/logger');

// JWT认证中间件
const protect = asyncHandler(async (req, res, next) => {
  let token;

  // 从请求头获取token
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
    try {
      // 提取token
      token = req.headers.authorization.split(' ')[1];

      // 验证token
      const decoded = jwt.verify(token, process.env.JWT_SECRET);

      // 检查Redis中的token黑名单
      const isBlacklisted = await cache.exists(`blacklist_${token}`);
      if (isBlacklisted) {
        res.status(401);
        throw new Error('Token has been invalidated');
      }

      // 从数据库获取用户信息
      const users = await query(
        'SELECT id, username, email, role, status, created_at FROM users WHERE id = ? AND status = "active"',
        [decoded.id]
      );

      if (users.length === 0) {
        res.status(401);
        throw new Error('User not found or inactive');
      }

      req.user = users[0];
      next();
    } catch (error) {
      logger.error('Auth middleware error:', error);
      res.status(401);
      throw new Error('Not authorized, token failed');
    }
  }

  if (!token) {
    res.status(401);
    throw new Error('Not authorized, no token');
  }
});

// 角色权限中间件
const authorize = (...roles) => {
  return (req, res, next) => {
    if (!req.user) {
      res.status(401);
      throw new Error('Not authorized');
    }

    if (!roles.includes(req.user.role)) {
      res.status(403);
      throw new Error('Access denied - insufficient permissions');
    }

    next();
  };
};

// 可选认证中间件（不强制要求登录）
const optionalAuth = asyncHandler(async (req, res, next) => {
  let token;

  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
    try {
      token = req.headers.authorization.split(' ')[1];
      const decoded = jwt.verify(token, process.env.JWT_SECRET);

      // 检查token是否在黑名单中
      const isBlacklisted = await cache.exists(`blacklist_${token}`);
      if (!isBlacklisted) {
        const users = await query(
          'SELECT id, username, email, role, status FROM users WHERE id = ? AND status = "active"',
          [decoded.id]
        );

        if (users.length > 0) {
          req.user = users[0];
        }
      }
    } catch (error) {
      // 可选认证失败时不抛出错误，继续执行
      logger.warn('Optional auth failed:', error.message);
    }
  }

  next();
});

// 生成JWT token
const generateToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRE || '30d'
  });
};

// 生成刷新token
const generateRefreshToken = (id) => {
  return jwt.sign({ id }, process.env.JWT_REFRESH_SECRET, {
    expiresIn: process.env.JWT_REFRESH_EXPIRE || '7d'
  });
};

// 验证刷新token
const verifyRefreshToken = (token) => {
  try {
    return jwt.verify(token, process.env.JWT_REFRESH_SECRET);
  } catch (error) {
    throw new Error('Invalid refresh token');
  }
};

module.exports = {
  protect,
  authorize,
  optionalAuth,
  generateToken,
  generateRefreshToken,
  verifyRefreshToken
};